#ifndef FRAMEWORK_H
#define FRAMEWORK_H

#include <QObject>
#include <QSettings>
#include <QString>
#include <QTranslator>

#include <plugin/plugin_global.h>
#include <plugin/plugin/PluginContext.h>
#include <plugin/service/LoggerService.h>
#include <plugin/util/AbstractSecurityContextHandler.h>
#include <plugin/util/PluginDescriptionManager.h>
#include <plugin/util/SiteManager.h>

namespace antu
{
namespace plugin
{

class PLUGINSHARED_EXPORT CloseSignal
{
private:
    bool m_bCanClose;

public:
    CloseSignal();

    bool canClose();

    void setCanClose(bool canClose);
};

class PLUGINSHARED_EXPORT Framework : public QObject
{
    Q_OBJECT

private:
    Framework();

    LoggerService* m_pLoggerService;
    QSettings* m_pSettingsManager;
    PluginDescriptionManager* m_pDescriptionManager;
    SiteManager* m_pSiteManager;
    AbstractSecurityContextHandler* m_pSecurityHandler;
    PluginContext* m_pPluginContext;

    QTranslator m_oTranslator;

    bool loadTranslationFile(const QString& translationFile);

public:
    ~Framework();

    /**
     * @brief Setup of the framework. This method should be called right after
     *        plugin context is created, and before plugin activator startup.
     * @param pContext Pointer to plugin context object.
     * @param pHandler Pointer to AbstractSecurityContextHandler that grants access to modules.
     *                 If nullptr is passed, all access rights are granted to all modules.
     */
    void setup(PluginContext* pContext, AbstractSecurityContextHandler* pHandler = nullptr);

    AbstractSecurityContextHandler* securityContextHandler();

    /**
     * @brief Provides logger.
     * @return Pointer to logger service.
     */
    LoggerService* logger();

    /**
     * @brief Provides settings manager that stores and retrieves application settings.
     * @return Pointer to settings manager.
     */
    QSettings* settingsManager();

    /**
     * @brief Plugin description manager.
     * @return Pointer to plugin description manager.
     */
    PluginDescriptionManager *descriptionManager();

    /**
     * @brief Update site manager.
     * @return Pointer to update sites manager.
     */
    SiteManager* siteManager();

    /**
     * @brief Allows one to replace log commands to log messages to
     *        different storage media, such as console, file, rolling file
     *        or database. At a single instance, the framework can support
     *        one log command.
     * @param pCommand
     */
    void setLogCommand(AbstractLogCommand* pCommand);

    PluginContext* context();

    bool loadTranslationFile(QTranslator& translator, const QString &translationFile);

    void stop(CloseSignal* pSignal);

public:
    static Framework Instance;

signals:
    void aboutToClose(CloseSignal* pSignal);
};
}
}

#endif // FRAMEWORK_H
